using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using 凌依.工具库;

public class UI组件_色彩拾取器 : UI基类, IBeginDragHandler, IDragHandler
{
    private Image 灰度图_image;
    private Image 色彩展示;
    private Image 结果色;
    private Image 指针图;
    public Slider 色彩条;
    private Image 原色_Image;
    private Canvas canvas;

    public RectTransform 指针;
    public RectTransform 灰度图;

    public Color 原色;

    public UI组件_进度输入条 R;
    public UI组件_进度输入条 G;
    public UI组件_进度输入条 B;
    public UI组件_进度输入条 S;
    public UI组件_进度输入条 V;
    public UI组件_进度输入条 A;

    private InputField 十六进制;

    public bool 转255禁进制;

    private void Start()
    {
        //初始化(原色);
    }

    private void 定位色彩(Color color)
    {
        float h, s, v;
        Color.RGBToHSV(color, out h, out s, out v);
        色彩条.value = 1-h;
        Color 纯色 = Color.HSVToRGB(h, 1, 1);
        灰度图_image.sprite = 生成渐变图(纯色);
        指针.anchoredPosition = new Vector2(254*s, 254*v);
        结果色.color = color;
        改变时调用?.Invoke(结果色.color);
    }

    private void 定位sv色彩(float s,float v,float h)
    {
        指针.anchoredPosition = new Vector2(254 * s, 254 * v);
        结果色.color = Color.HSVToRGB(h, s, v);
    }

    private void 根据颜色计算滑动条(Color color)
    {
        float h, s, v;
        Color.RGBToHSV(color, out h, out s, out v);

        R.同步进度(color.r);
        G.同步进度(color.g);
        B.同步进度(color.b);
        A.同步进度(color.a);
        S.同步进度(s);
        V.同步进度(v);
    }

    private void SV背景色计算(Color color)
    {
        float h, s, v;
        Color.RGBToHSV(color, out h, out s, out v);
        Color color1 = Color.HSVToRGB(h, 1, 1);

        Texture2D texture2DS = new Texture2D(50, 1);
        Texture2D texture2DV = new Texture2D(50, 1);
        Texture2D texture2DA = new Texture2D(50, 1);
        Color 透明 = new Color(color1.r, color1.g, color1.b, 0);
        for (int x = 0; x < 50; x++)
        {
            texture2DS.SetPixel(x, 0, Color.Lerp(Color.white, color1, x / 50f));
            texture2DV.SetPixel(x, 0, Color.Lerp(Color.black, Color.Lerp(Color.white,color1,s), x / 50f));
            texture2DA.SetPixel(x, 0, Color.Lerp(透明, color1, x / 50f));
        }
        texture2DS.Apply();
        texture2DV.Apply();
        texture2DA.Apply();
        S.背景.sprite = Texture2D_工具.贴图转精灵(texture2DS);
        V.背景.sprite = Texture2D_工具.贴图转精灵(texture2DV);
        A.背景.sprite = Texture2D_工具.贴图转精灵(texture2DA);
    }

    #region 滑动值改变时

    private void R改变背景色(float value)
    {
        Color GR = new Color(value, 1, B.进度条.value);
        Color GL = new Color(value, 0, B.进度条.value);

        Color BR = new Color(value, G.进度条.value, 1);
        Color BL = new Color(value, G.进度条.value, 0);

        Texture2D texture2DG = new Texture2D(50, 1);
        Texture2D texture2DB = new Texture2D(50, 1);

        for (int x = 0; x < 50; x++)
        {
            texture2DG.SetPixel(x, 0, Color.Lerp(GL, GR, x / 50f));
            texture2DB.SetPixel(x, 0, Color.Lerp(BL, BR, x / 50f));
        }
        texture2DG.Apply();
        texture2DB.Apply();

        G.背景.sprite = Texture2D_工具.贴图转精灵(texture2DG);
        B.背景.sprite = Texture2D_工具.贴图转精灵(texture2DB);
    }
    private void G改变背景色(float value)
    {
        Color RR = new Color(1, value, B.进度条.value);
        Color RL = new Color(0, value, B.进度条.value);

        Color BR = new Color(R.进度条.value, value, 1);
        Color BL = new Color(R.进度条.value, value, 0);

        Texture2D texture2DR = new Texture2D(50, 1);
        Texture2D texture2DB = new Texture2D(50, 1);

        for (int x = 0; x < 50; x++)
        {
            texture2DR.SetPixel(x, 0, Color.Lerp(RL, RR, x / 50f));
            texture2DB.SetPixel(x, 0, Color.Lerp(BL, BR, x / 50f));
        }
        texture2DR.Apply();
        texture2DB.Apply();

        R.背景.sprite = Texture2D_工具.贴图转精灵(texture2DR);
        B.背景.sprite = Texture2D_工具.贴图转精灵(texture2DB);
    }
    private void B改变背景色(float value)
    {
        Color RR = new Color(1, G.进度条.value, value);
        Color RL = new Color(0, G.进度条.value, value);

        Color GR = new Color(R.进度条.value, 1, value);
        Color GL = new Color(R.进度条.value, 0, value);

        Texture2D texture2DR = new Texture2D(50, 1);
        Texture2D texture2DG = new Texture2D(50, 1);

        for (int x = 0; x < 50; x++)
        {
            texture2DR.SetPixel(x, 0, Color.Lerp(RL, RR, x / 50f));
            texture2DG.SetPixel(x, 0, Color.Lerp(GL, GR, x / 50f));
        }
        texture2DR.Apply();
        texture2DG.Apply();

        G.背景.sprite = Texture2D_工具.贴图转精灵(texture2DG);
        R.背景.sprite = Texture2D_工具.贴图转精灵(texture2DR);
    }


    private void R值改变时(float value)
    {
        Color color = new Color(value, G.进度条.value, B.进度条.value);
        定位色彩(color);
        R改变背景色(value);
        计算十六进制();
    }
    private void G值改变时(float value)
    {
        Color color = new Color(结果色.color.r, value, 结果色.color.b);
        定位色彩(color);

        G改变背景色(value);
        计算十六进制();
    }
    private void B值改变时(float value)
    {
        Color color = new Color(结果色.color.r, 结果色.color.g, value);
        定位色彩(color);

        B改变背景色(value);
        计算十六进制();
    }

    private void A值改变时(float value)
    {
        结果色.color = new Color(结果色.color.r, 结果色.color.g, 结果色.color.b, value);
        改变时调用?.Invoke(结果色.color);
        计算十六进制();
    }

    private void S值背景色(float value)
    {
        Color RR = new Color(1, G.进度条.value, B.进度条.value);
        Color RL = new Color(0, G.进度条.value, B.进度条.value);
        Color GR = new Color(R.进度条.value, 1, B.进度条.value);
        Color GL = new Color(R.进度条.value, 0, B.进度条.value);
        Color BR = new Color(R.进度条.value, G.进度条.value, 1);
        Color BL = new Color(R.进度条.value, G.进度条.value, 0);

        float h, s, v;
        float va = value;
        Color.RGBToHSV(结果色.color, out h, out s, out v);
        Color color1 = Color.HSVToRGB(h, 1, 1);
        va = Mathf.Clamp(va, 0.01f, 1);

        Texture2D texture2DR = new Texture2D(50, 1);
        Texture2D texture2DG = new Texture2D(50, 1);
        Texture2D texture2DV = new Texture2D(50, 1);
        Texture2D texture2DB = new Texture2D(50, 1);

        for (int x = 0; x < 50; x++)
        {
            texture2DR.SetPixel(x, 0, Color.Lerp(RL, Color.Lerp(RR,Color.white, 1- va), x / 50f));
            texture2DB.SetPixel(x, 0, Color.Lerp(BL, Color.Lerp(BR, Color.white,1- va), x / 50f));
            texture2DG.SetPixel(x, 0, Color.Lerp(GL, Color.Lerp(GR, Color.white, 1- va), x / 50f));
            texture2DV.SetPixel(x, 0, Color.Lerp(Color.black, Color.Lerp(Color.white, color1, s), x / 50f));
        }
        texture2DR.Apply();
        texture2DB.Apply();
        texture2DV.Apply();
        texture2DG.Apply();

        G.背景.sprite = Texture2D_工具.贴图转精灵(texture2DG);
        B.背景.sprite = Texture2D_工具.贴图转精灵(texture2DB);
        R.背景.sprite = Texture2D_工具.贴图转精灵(texture2DR);
        V.背景.sprite = Texture2D_工具.贴图转精灵(texture2DV);

        
        
    }
    private void V值背景色(float value)//未完成
    {
        float va = value;
        va = Mathf.Clamp(va, 0.00f, 0.99f);

        Color 灰度值 = new Color(va, va, va);

        Color RR = new Color(1, G.进度条.value, B.进度条.value);
        Color RL = new Color(0, G.进度条.value, B.进度条.value);
        Color GR = new Color(R.进度条.value, 1, B.进度条.value);
        Color GL = new Color(R.进度条.value, 0, B.进度条.value);
        Color BR = new Color(R.进度条.value, G.进度条.value, 1);
        Color BL = new Color(R.进度条.value, G.进度条.value, 0);

        Texture2D texture2DR = new Texture2D(50, 1);
        Texture2D texture2DG = new Texture2D(50, 1);
        Texture2D texture2DB = new Texture2D(50, 1);
        Texture2D texture2DV = new Texture2D(50, 1);

        float h, s, v;
        Color.RGBToHSV(结果色.color, out h, out s, out v);
        Color color1 = Color.HSVToRGB(h, 1, 1);

        for (int x = 0; x < 50; x++)
        {
            texture2DR.SetPixel(x, 0, Color.Lerp(RL * 灰度值, RR, x / 50f));
            texture2DB.SetPixel(x, 0, Color.Lerp(GL * 灰度值, BR, x / 50f));
            texture2DG.SetPixel(x, 0, Color.Lerp(BL * 灰度值, GR, x / 50f));
            texture2DV.SetPixel(x, 0, Color.Lerp(Color.white * 灰度值, color1 * 灰度值, x / 50f));
        }
        texture2DR.Apply();
        texture2DB.Apply();
        texture2DG.Apply();
        texture2DV.Apply();


        G.背景.sprite = Texture2D_工具.贴图转精灵(texture2DG);
        B.背景.sprite = Texture2D_工具.贴图转精灵(texture2DB);
        R.背景.sprite = Texture2D_工具.贴图转精灵(texture2DR);
        S.背景.sprite = Texture2D_工具.贴图转精灵(texture2DV);

        

       
    }

    private void S值改变时(float value)
    {
        float h, s, v;

        Color.RGBToHSV(结果色.color, out h, out s, out v);

        s = value; Color color = Color.HSVToRGB(h, s, v);

        定位sv色彩(s,v,h);
        根据颜色计算滑动条(color);
        S值背景色(value);
        改变时调用?.Invoke(结果色.color);
        计算十六进制();
    }
    private void V值改变时(float value)
    {
        float h, s, v;

        Color.RGBToHSV(结果色.color, out h, out s, out v);

        v = value; Color color = Color.HSVToRGB(h, s, v);

        定位sv色彩(s, v, h);
        根据颜色计算滑动条(color);
        V值背景色(value);
        改变时调用?.Invoke(结果色.color);
        计算十六进制();
    }

    #endregion


    private UnityAction<Color> 改变时调用;
    private UnityAction 销毁时;
    private IEnumerator 重置色彩_携程()
    {
        yield return 0;
        重置色彩();
    }
    public void 初始化(Color 原色,UnityAction<Color> 改变时调用=null,UnityAction 销毁时=null)
    {
        灰度图_image = 查找控件<Image>("灰度图");
        色彩展示 = 查找控件<Image>("色彩展示图");
        结果色 = 查找控件<Image>("结果色");
        原色_Image = 查找控件<Image>("原色");
        指针图 = 指针.GetComponent<Image>();
        十六进制 = 查找控件<InputField>("十六进制");

        this.改变时调用 = 改变时调用;
        this.销毁时 = 销毁时;
        //this.改变时调用 += 根据颜色计算滑动条;

        this.原色 = 原色;
        转255缓存 = 转255禁进制;
        R.转255进制 = 转255禁进制;
        G.转255进制 = 转255禁进制;
        B.转255进制 = 转255禁进制;
        A.转255进制 = 转255禁进制;

        R.初始化(0, R值改变时);
        G.初始化(0, G值改变时);
        B.初始化(0, B值改变时);
        A.初始化(原色.a, A值改变时);
        S.初始化(0, S值改变时);
        V.初始化(0, V值改变时);

        
        StartCoroutine(重置色彩_携程());
        色彩展示.sprite = 生成色彩图();
        canvas = GameObject.Find("Canvas").GetComponent<Canvas>();
        原色_Image.color = 原色;

        S.禁止拖至为零 = true;
        V.禁止拖至为零 = true;

    }

    public Color 获取颜色()
    {
        return 结果色.color;
    }
    public override void 销毁面板()
    {
        base.销毁面板();
        销毁时?.Invoke();
    }

    private void 重置色彩()
    {
        定位色彩(原色);
        R改变背景色(结果色.color.r);
        G改变背景色(结果色.color.g);
        B改变背景色(结果色.color.b);
        SV背景色计算(结果色.color);
    }

    protected override void 点击事件(string 按钮名)
    {
        base.点击事件(按钮名);
        switch (按钮名)
        {
            case "关闭按钮":
                销毁面板();
                break;
            case "重置按钮":
                重置色彩();
                break;

            case "确定按钮":
                改变时调用?.Invoke(结果色.color);
                销毁面板();
                break;
            default:
                break;
        }
    }

    protected override void 单选按钮(string 单选按钮名, bool 值)
    {
        base.单选按钮(单选按钮名, 值);
        转255禁进制 = 值;
    }

    private Sprite 生成渐变图(Color 基色)
    {
        Texture2D 展示图 = new Texture2D(100, 100);

        for (int y = 0; y < 100; y++)
        {
            for (int x = 0; x < 100; x++)
            {
                Color 添加色 = Color.Lerp(
                    Color.Lerp(Color.white, Color.black, 1 - y / 99f),
                    Color.Lerp(基色, Color.black, 1 - y / 99f),
                    x / 99f);

                展示图.SetPixel(x, y, 添加色);
            }
        }

        展示图.Apply();
        return Texture2D_工具.贴图转精灵(展示图);
    }
    private Sprite 生成色彩图()
    {
        Texture2D 展示图 = new Texture2D(1, 500);

        for (int y = 0; y < 500; y++)
            展示图.SetPixel(0, y, Color.HSVToRGB(y / 500f, 1, 1));

        展示图.Apply();
        return Texture2D_工具.贴图转精灵(展示图);
    }

    bool 鼠标按住;
    private bool 转255缓存;
    private void Update()
    {
        if (转255缓存 != 转255禁进制)
        {
            R.转255进制 = 转255禁进制;
            G.转255进制 = 转255禁进制;
            A.转255进制 = 转255禁进制;
            B.转255进制 = 转255禁进制;
            R.同步进度(R.进度条.value);
            G.同步进度(G.进度条.value);
            B.同步进度(B.进度条.value);
            A.同步进度(A.进度条.value);
            转255缓存 = 转255禁进制;
        }
        

        if (Input.GetMouseButtonDown(0))
        {
            Vector2 pos;
            if (RectTransformUtility.ScreenPointToLocalPointInRectangle(灰度图, Input.mousePosition, canvas.worldCamera, out pos))
            {
                if (pos.x < 1 || pos.x > 254 || pos.y < 1 || pos.y > 254)
                {
                    暂停拖动 = false;
                    return;
                }
                鼠标按住 = true;
            }
        }
        if (Input.GetMouseButtonUp(0))
            鼠标按住 = false;

        if (鼠标按住)
        {
            Vector2 pos;
            if (RectTransformUtility.ScreenPointToLocalPointInRectangle(灰度图, Input.mousePosition, canvas.worldCamera, out pos))
            {
                pos.x = Mathf.Clamp(pos.x, 1, 253);
                pos.y = Mathf.Clamp(pos.y, 1, 253);

                指针.anchoredPosition = pos;
                if (pos.x < 76 && pos.y > 178)
                    指针图.color = Color.black;
                else
                    指针图.color = Color.white;

                结果色.color = Color.HSVToRGB(Mathf.Abs(1 - 色彩条.value), 指针.anchoredPosition.x / 254f, 指针.anchoredPosition.y / 254f);


                改变时调用?.Invoke(结果色.color);

                暂停拖动 = true;

                根据颜色计算滑动条(结果色.color);
                R改变背景色(结果色.color.r);
                G改变背景色(结果色.color.g);
                B改变背景色(结果色.color.b);
                SV背景色计算(结果色.color);
                计算十六进制();
            }
        }
    }

    bool 暂停拖动 = false;

    private void 计算十六进制()
    {
        string 保证两字符(string 十六进制)=> 十六进制.Length == 1 ? "0" + 十六进制 : 十六进制;

        十六进制.text = $"{保证两字符(进制转换.十转十六((int)(R.进度条.value * 255)))}{保证两字符(进制转换.十转十六((int)(G.进度条.value * 255)))}{保证两字符(进制转换.十转十六((int)(B.进度条.value * 255)))}{保证两字符(进制转换.十转十六((int)(A.进度条.value * 255)))}";
        缓存上次可用值 = 十六进制.text;
    }

    private string 缓存上次可用值;
    public void 输入完成时()
    {
        try
        {
            float r, g, b, a=1;
            if (十六进制.text.Length==6)
            {
                r = 进制转换.十六转十($"{十六进制.text[0]}{十六进制.text[1]}") / 255f;
                g = 进制转换.十六转十($"{十六进制.text[2]}{十六进制.text[3]}") / 255f;
                b = 进制转换.十六转十($"{十六进制.text[4]}{十六进制.text[5]}") / 255f;
            }
            else if(十六进制.text.Length == 8)
            {
                 r = 进制转换.十六转十($"{十六进制.text[0]}{十六进制.text[1]}") / 255f;
                 g = 进制转换.十六转十($"{十六进制.text[2]}{十六进制.text[3]}") / 255f;
                 b = 进制转换.十六转十($"{十六进制.text[4]}{十六进制.text[5]}") / 255f;
                 a = 进制转换.十六转十($"{十六进制.text[6]}{十六进制.text[7]}") / 255f;
            }
            else
            {
                十六进制.text = 缓存上次可用值;
                return;
            }
           

            Color color = new Color(r, g, b, a);

            定位色彩(color);
            根据颜色计算滑动条(color);

            缓存上次可用值 = 十六进制.text;
        }
        catch
        {
            十六进制.text = 缓存上次可用值;
        }
    }

    float 缓存 = 0;
    private void FixedUpdate()
    {
        float 色彩进度 = Mathf.Abs(1-色彩条.value);
        if (色彩进度 == 缓存)
            return;
        缓存 = 色彩进度;
        Color color1 = Color.HSVToRGB(色彩进度, 1, 1);
        灰度图_image.sprite = 生成渐变图(color1);
        Color color = Color.HSVToRGB(色彩进度, 指针.anchoredPosition.x/254f, 指针.anchoredPosition.y / 254f);
        结果色.color = color;
        SV背景色计算(color);
        B改变背景色(color.b);
        R改变背景色(color.r);
        G改变背景色(color.g);
        根据颜色计算滑动条(结果色.color);
        计算十六进制();

        改变时调用?.Invoke(结果色.color);
    }


    Vector2 位置偏移;
    public void OnBeginDrag(PointerEventData eventData)
    {
        if (!暂停拖动)
            位置偏移 = eventData.position - new Vector2(transform.position.x, transform.position.y);
    }

    public void OnDrag(PointerEventData eventData)
    {
        if(!暂停拖动)
            transform.position = eventData.position - 位置偏移;
    }
}
